package com.wj.dubbo.service.crawler.service.impl;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.dubbo.common.utils.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.wj.console.common.exception.BusinessException;
import com.wj.console.constant.Enums.RESULT_CODE;
import com.wj.console.rabbit.message.CrawlerSocialFundMessage;
import com.wj.dubbo.service.common.RedisBillLockHandler;
import com.wj.dubbo.service.common.lock.GenericBillIdentify;
import com.wj.dubbo.service.crawler.entity.CrawlerSfManager;
import com.wj.dubbo.service.crawler.entity.CrawlerSocialInfo;
import com.wj.dubbo.service.crawler.entity.CrawlerSocialSummary;
import com.wj.dubbo.service.crawler.entity.CrawlerSocialSummaryItem;
import com.wj.dubbo.service.crawler.entity.OmMemberMessage;
import com.wj.dubbo.utils.DateUtils;
import com.wj.dubbo.utils.DesUtil;
import com.wj.dubbo.utils.JuheUtils;
import com.wj.dubbo.utils.UUIDUtils;

@Service
public class CrawlSocialService {
	
	private static final Logger log = LoggerFactory.getLogger(CrawlSocialService.class);

	public static final String DOMAIN_URL = "http://www.bjrbj.gov.cn";
	public static final String BJGJJ_URL = "http://www.bjgjj.gov.cn/wsyw/wscx/gjjcx-login.jsp";
	public static final String GJJCX_URL = "http://www.bjgjj.gov.cn/wsyw/wscx/gjjcx-choice.jsp";
	public static final String DEF_CHATSET = "UTF-8";
	public static final int DEF_CONN_TIMEOUT = 30000;
	public static final int DEF_READ_TIMEOUT = 30000;
	public static String userAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.66 Safari/537.36";

	public static String jfxxchx = "http://www.bjrbj.gov.cn/csibiz/indinfo/search/ind/indPaySearchAction!oldage?searchYear=2017&time=1491532978726";

	public static String login = "/csibiz/indinfo/login_check";

	public static String index = "/csibiz/indinfo/login.jsp";

	public static String yzhm = "/csibiz/indinfo/validationCodeServlet.do";

	public static String info = "/csibiz/indinfo/search/ind/indNewInfoSearchAction";

	public static String social = "/csibiz/indinfo/search/ind/indPaySearchAction!%s?searchYear=%s&time=%s";
	
	@Autowired
	private CrawlerSfManagerServiceImpl managerService;

	@Autowired
	private CrawlerSocialInfoServiceImpl socialInfoService;
	
	@Autowired
	private CrawlerSocialSummaryServiceImpl socialSummaryService;
	
	@Autowired
	private CrawlerSocialSummaryItemServiceImpl socialSummaryItemService;
	
	@Autowired
	private RedisBillLockHandler redisBillLockHandler;
	
	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	public static Map<String, String> socialMap=new HashMap<String, String>();
	
	
	static{
		socialMap.put("oldage", "养老保险");
		socialMap.put("unemployment", "失业保险");
		socialMap.put("injuries", "工伤保险");
		socialMap.put("maternity", "生育保险");
		socialMap.put("medicalcare", "医疗保险");
	}

	public String doLogin(Map<String, String> map, Map<String, String> cookies) throws Exception {
		// 解析登录返回数据
		Document doc = null;
		int count = 0;
		while (true) {
			if (count == 3) {
				return RESULT_CODE.VERIFICATION_CODE_ERROR.key;
			}
			// 登录
			doc = login(map, cookies);
			if (null != doc) {
				log.info(doc.toString());
				String loginStatus = analysisLoginData(doc);
				log.info("登录返回状态："+loginStatus);
				if (StringUtils.isEquals(loginStatus, RESULT_CODE.SUCCESS.key)) {// 登录成功
					return RESULT_CODE.SUCCESS.key;
				} else if (StringUtils.isEquals(loginStatus, RESULT_CODE.FAILURE.key)) {// 登录失败
					return RESULT_CODE.FAILURE.key;
				} else if (StringUtils.isEquals(loginStatus, RESULT_CODE.PASSWORD_ERROR.key)) {// 密码错误
					return RESULT_CODE.PASSWORD_ERROR.key;
				} else if (StringUtils.isEquals(loginStatus, RESULT_CODE.SOCIAL_LOCK.key)) {// 本账号因为错误密码输入次数过多，已经被锁定，请次日再试
					return RESULT_CODE.SOCIAL_LOCK.key;
				} else if (StringUtils.isEquals(loginStatus, RESULT_CODE.VERIFICATION_CODE_ERROR.key)) {// 验证码错误
					// 返回后尝试再次自动登录
					count++;
					continue;
				}else if(StringUtils.isEquals(loginStatus, RESULT_CODE.SYSTERM_MAINTAIN.key)){//社保维护
					return RESULT_CODE.SYSTERM_MAINTAIN.key;
				}
			}else{
				return RESULT_CODE.FAILURE.key;
			}
		}

	}

	/**
	 * 登录
	 * @param map
	 * @param cookies
	 * @return
	 */
	public Document login(Map<String, String> map, Map<String, String> cookies) {
		try {
			// 请求验证码
			String code = getVerificationCode(DOMAIN_URL + yzhm, cookies);
			HashMap<String, String> params = new HashMap<String, String>();
			params.put("type", "1");
			params.put("flag", "3");// 身份证类型
			params.put("j_username", map.get("identityId"));// 身份证号
			params.put("j_password", DesUtil.decrypt(map.get("pwd"), "KXDCRAWLER"));// 密码
			params.put("safecode", code);
			Document resp = Jsoup.connect(DOMAIN_URL + login).cookies(cookies).data(params).followRedirects(true).post();
			return resp;
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 获取验证码
	 */
	private String getVerificationCode(String url, Map<String, String> cookies) {
		String verificationCode = "";
		FileOutputStream fosImg = null;
		File fileLoginImg = null;
		try {
			// 验证码图片
			Response resLoginImg = Jsoup.connect(url).cookies(cookies).ignoreContentType(true).execute();
			// C:\Users\ADMINI~1\AppData\Local\Temp\
			fileLoginImg = new File(System.getProperty("java.io.tmpdir") + UUIDUtils.getUUIDStr() + ".png");
			fosImg = new FileOutputStream(fileLoginImg);
			fosImg.write(resLoginImg.bodyAsBytes());
	        // 调用juhe识别验证码
    		String jsonStr = JuheUtils.post("8001", fileLoginImg);
    		JSONObject jsonObj = JSONObject.parseObject(jsonStr);
    		verificationCode = (String) jsonObj.get("result");
		} catch (Exception e) {
			log.error("Juhe VerificationCode Error", e);
		} finally {
			if(fileLoginImg!=null && fileLoginImg.isFile()){
				fileLoginImg.delete();
			}
			if(fosImg!=null){
				try {
					fosImg.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
		}
		log.info("验证码：" + verificationCode);
		return verificationCode;
	}
	
	

	/**
	 * 解析登录返回的数据
	 * 
	 * @throws IOException
	 */
	public String analysisLoginData(Document doc) throws IOException {
		String loginStatus = RESULT_CODE.FAILURE.key;
		// 登录状态
		if (StringUtils.isEquals(doc.location(), "http://www.bjrbj.gov.cn/csibiz/indinfo/index.jsp")) {
			loginStatus = RESULT_CODE.SUCCESS.key;//登录成功
		}else{
			Elements tabs = doc.select("table");
			if (null != tabs && tabs.size() == 4) {
				String loginMsg = doc.select("table").get(3).select("span").text().trim();
				log.info("登录返回信息:"+loginMsg);
				if (StringUtils.isEquals(loginMsg, "附加码有误")) {
					loginStatus = RESULT_CODE.VERIFICATION_CODE_ERROR.key;// 验证码错误
				} else if (StringUtils.isEquals(loginMsg, "输入的密码验证错误")) {
					loginStatus = RESULT_CODE.PASSWORD_ERROR.key;// 密码错误，用户重新登录
				} else if (StringUtils.isEquals(loginMsg, "本账号因为错误密码输入次数过多，已经被锁定，请次日再试")) {
					loginStatus = RESULT_CODE.SOCIAL_LOCK.key;// 密码错误，用户重新登录
				}
			}
			if (doc.text().contains("在此期间系统暂停服务")) {
				loginStatus = RESULT_CODE.SYSTERM_MAINTAIN.key;// 系统维护
			}
		}
		log.info("登录返回码："+loginStatus);
		return loginStatus;
	}

	/**
	 * 爬取数据
	 * 
	 * @param url
	 * @param cookies
	 * @param param
	 * @return
	 * @throws IOException
	 */
	public Document crawlData(String url, Map<String, String> cookies, Map<String, String> param) throws IOException {
		Document doc = Jsoup.connect(url).cookies(cookies).data(param).followRedirects(true).post();
		return doc;
	}

	/**
	 * 爬取数据
	 * 
	 * @param url
	 * @param cookies
	 * @return
	 * @throws IOException
	 */
	public Document crawlData(String url, Map<String, String> cookies) throws IOException {
		Document doc = Jsoup.connect(url).cookies(cookies).followRedirects(true).post();
		return doc;
	}

	/**
	 * 爬取个人信息数据
	 * 
	 * @throws IOException
	 */
	public void crawlPersionInfoData(Map<String, String> cookies,Map<String, String> map) throws IOException {
		analysisPersionInfoData(crawlData(DOMAIN_URL + info, cookies),map);
	}

	/**
	 * 解析个人信息数据
	 */
	private void analysisPersionInfoData(Document doc,Map<String, String> map) {
		try {
			// 公司名称
			String company = doc.select("table").get(0).select("tr").get(0).select("td").get(0).text().split(" ")[1].replace(" ", "").trim();
			// 姓名
			String name = doc.select("table").get(1).select("tr").get(1).select("td").get(1).text();
			//申报金额 社保基数
			String base=doc.select("#printForm > table:nth-child(5) > tbody > tr:nth-child(11) > td:nth-child(6)").text();
			//社保状态
			String status=doc.select("#printForm > table:nth-child(5) > tbody > tr:nth-child(1) > td:nth-child(2)").text().split(" ")[5];
			status=status.replace("(", "").replace(")", "").replace("]", "");
			map.put("company", company);
			map.put("name", name);
			map.put("base", base);
			map.put("status", status);
		} catch (Exception e) {
			log.error("爬取个人信息数据异常，结构可能改变",e);
		}
	}

	/**
	 * 获取cookie
	 * 
	 * @return
	 * @throws IOException
	 */
	private Map<String, String> getCookies() throws IOException {
		Response rep = Jsoup.connect(DOMAIN_URL + index).execute();
		return rep.cookies();
	}

	
	@Transactional
	public CrawlerSocialFundMessage crawSocialData(CrawlerSocialFundMessage message) throws Exception {
		
		/** 加锁 */
		String key = message.getIdentityId();
		GenericBillIdentify billIdentify = new GenericBillIdentify("social:" + key);
		
		try{
			if(!redisBillLockHandler.tryLock(billIdentify)){
				//throw new BusinessException(RESULT_CODE.SYSTERM_MAINTAIN.key, "已经有请求在处理，请稍后再试。");
				return null;
			}
			Map<String, String> map = new HashMap<String, String>();
			map.put("identityId", message.getIdentityId().toUpperCase());
			map.put("pwd", message.getPwd());
			map.put("memberId", message.getMemberId());
			// 获取cookies
			Map<String, String> cookies = getCookies();
			// 登录返回登录状态
			String status = doLogin(map, cookies);
	
			Map<String,Map<String,CrawlerSocialSummaryItem>> sm=new TreeMap<String,Map<String,CrawlerSocialSummaryItem>>();
			if (StringUtils.isEquals(status, RESULT_CODE.SUCCESS.key)) {// 登录成功
				// 获取个人信息
				crawlPersionInfoData(cookies,map);
				// 爬取数据 封装数据
				sm=crawlAllSocialData(cookies, message,map);
				// 保存更新账户信息 登录失败要修改 状态
				map.put("managerId", saveSocialManagerData(map, status, message));
				// 保存或更新社保信息数据
				saveSocialInfoData(map);
				// 保存社保所有数据、或者追加新的社保数据
				String payTime=saveSocialData(sm,map);
				//更新info数据
				updateSocialInfoData(map.get("managerId"),payTime);
			}else{
				// 保存更新账户信息 登录失败要修改 状态
				saveSocialManagerData(map, status, message);
			}
			return setData(map, status,message.getIsPush());
		}finally{
			redisBillLockHandler.unLock(billIdentify);
		}
	} 

	/**
	 * 更新info数据
	 * @param managerId 
	 * @param payTime 
	 */
	private void updateSocialInfoData(String managerId, String payTime) {
		Wrapper<CrawlerSocialInfo> socialInfo = new EntityWrapper<CrawlerSocialInfo>();
		socialInfo.eq("manager_id",managerId);
		// 社保信息
		CrawlerSocialInfo info = socialInfoService.selectOne(socialInfo);
		if (info!=null) {
			Wrapper<CrawlerSocialSummary> summary = new EntityWrapper<CrawlerSocialSummary>();
			summary.eq("manager_id", managerId);
//			socialInfo.ne("com_amount", 0);
			summary.gt("com_amount",0);
			// 社保信息
			int summaryCount = socialSummaryService.selectCount(summary);
			info.setPayYearMonth(payTime);
			info.setPayMonthCount(summaryCount);
			socialInfoService.updateById(info);
		}
	}

	private String saveSocialData(Map<String, Map<String, CrawlerSocialSummaryItem>> sm, Map<String, String> map) throws Exception {
		String managerId=map.get("managerId");
		List<CrawlerSocialSummary> sumList=new ArrayList<CrawlerSocialSummary>();
		List<CrawlerSocialSummaryItem> itemList=new ArrayList<CrawlerSocialSummaryItem>();
		for (Entry<String, Map<String, CrawlerSocialSummaryItem>> m : sm.entrySet()) {
			//创建summary数据
			CrawlerSocialSummary summary=new CrawlerSocialSummary();
			summary.setId(UUIDUtils.getUUIDStr());
			summary.setManagerId(managerId);
			summary.setPayYearMonth(m.getKey());
			summary.setCreateTime(new Date());
			
			BigDecimal perAmount=new BigDecimal(0);
			BigDecimal comAmount=new BigDecimal(0);
			String companyName="";
			
			for (Entry<String, CrawlerSocialSummaryItem> social : m.getValue().entrySet()) {
				if (StringUtils.isEquals(social.getKey(), "oldage")) {
					companyName=social.getValue().getCompanyName();
				}
				perAmount=perAmount.add(social.getValue().getPerAmount());
				comAmount=comAmount.add(social.getValue().getComAmount());
				social.getValue().setSummaryId(summary.getId());
				itemList.add(social.getValue());
			}
			summary.setComAmount(comAmount);
			summary.setPerAmount(perAmount);
			summary.setCompanyName(companyName);
			sumList.add(summary);
		}
		
		
		if (sumList!=null&&sumList.size()>0) {
			log.info("删除社保最近缴纳日期12个月前所在年份以后的数据【start】");
			String crawlYear=map.get("crawlYear");
			log.info("crawlYear:"+crawlYear);
			
			// 取最近一次的日期
//			String year = sumList.get(0).getPayYearMonth().split("-")[0];
//			log.info("取最近一次的日期:"+year);
			//查询重复数据summary表中最近缴纳日期年份和4月前所在年份的数据
			List<CrawlerSocialSummary> sum=socialSummaryService.queryByYear(crawlYear,managerId);
			log.info(sum.toString());
			if (sum.size()>0) {
				//删除重复数据summaryItem表中最近缴纳日期年份和12月前所在年份的数据
				socialSummaryItemService.deleteBySummaryId(sum);
				//删除重复数据summary表中最近缴纳日期年份和12月前所在年份的数据
				socialSummaryService.deleteSummaryByYears(crawlYear,managerId);
			}
			log.info("删除社保最近缴纳日期年份和4月前所在年份的数据【end】");
			
			int index=-1;
			for (int i = sumList.size()-1; i >=0; i--) {
				BigDecimal zero=new BigDecimal(0);
				if(index==-1){
					if (sumList.get(i).getPerAmount().compareTo(zero)==1&&sumList.get(i).getComAmount().compareTo(zero)==1) {
						index=-2;
						sumList.get(i).setPayStatus("1");//已缴
						continue;
					}else{
						sumList.get(i).setPayStatus("2");//无法判断状态数据
					}
				}
				if (index==-2) {
					if (sumList.get(i).getPerAmount().compareTo(zero)==0&&sumList.get(i).getComAmount().compareTo(zero)==0){
						sumList.get(i).setPayStatus("0");//断交
					}else{
						sumList.get(i).setPayStatus("1");//断交
					}
				}
			}
			
			//保存summary
			socialSummaryService.insertBatch(sumList);
			//保存summaryItem
			socialSummaryItemService.insertBatch(itemList);
			//返回最近缴纳日期
			return sumList.get(sumList.size()-3).getPayYearMonth();
			
		}
		
		return "";
	}
	

	/**
	 * 爬取社保数据
	 * @param cookies
	 * @param message
	 * @param map 
	 * @return
	 * @throws Exception
	 */
	private Map<String,Map<String,CrawlerSocialSummaryItem>> crawlAllSocialData(Map<String, String> cookies, CrawlerSocialFundMessage message, Map<String, String> map) throws Exception {

		Wrapper<CrawlerSocialInfo> socialInfo = new EntityWrapper<CrawlerSocialInfo>();
		socialInfo.eq("manager_id", message.getId());
		// 社保信息
		CrawlerSocialInfo info = socialInfoService.selectOne(socialInfo);
		// 北京最早公积金缴纳年份
		int nextYear = 1996;
		if (info != null) {
			// 取最近一次的日期
			String y = info.getPayYearMonth();
			nextYear = DateUtils.getCrawlYear(y);//12个月
		}
		map.put("crawlYear", nextYear+"");
		Map<String, List<CrawlerSocialSummaryItem>> typeListMap=new HashMap<String, List<CrawlerSocialSummaryItem>>();
		List<CrawlerSocialSummaryItem> oldageList = new ArrayList<CrawlerSocialSummaryItem>();
		List<CrawlerSocialSummaryItem> unemploymentList = new ArrayList<CrawlerSocialSummaryItem>();
		List<CrawlerSocialSummaryItem> injuriesList = new ArrayList<CrawlerSocialSummaryItem>();
		List<CrawlerSocialSummaryItem> maternityList = new ArrayList<CrawlerSocialSummaryItem>();
		List<CrawlerSocialSummaryItem> medicalcareList = new ArrayList<CrawlerSocialSummaryItem>();

		int nowYear=DateUtils.getNowYear();
		for (int year = nextYear; year <=nowYear ; year++) {
			// 养老 oldage
			Document oldage = crawlSocialByType("oldage", cookies, year);
			analysisSocialData(oldage, oldageList, "oldage",year);

			// 失业 unemployment
			Document unemployment = crawlSocialByType("unemployment", cookies, year);
			analysisSocialData(unemployment, unemploymentList, "unemployment",year);

			// 工伤 injuries
			Document injuries = crawlSocialByType("injuries", cookies, year);
			analysisSocialData(injuries, injuriesList, "injuries",year);

			// 生育 maternity
			Document maternity = crawlSocialByType("maternity", cookies, year);
			analysisSocialData(maternity, maternityList, "maternity",year);

			// 医疗 medicalcare
			Document medicalcare = crawlSocialByType("medicalcare", cookies, year);
			analysisSocialData(medicalcare, medicalcareList, "medicalcare",year);

		}
		
		typeListMap.put("oldage", oldageList);
		typeListMap.put("unemployment", unemploymentList);
		typeListMap.put("injuries", injuriesList);
		typeListMap.put("maternity", maternityList);
		typeListMap.put("medicalcare", medicalcareList);

		return createByDateAndTypeMap(typeListMap);
	}
	
	/**
	 * 按年月和类型分类
	 * @param typeListMap
	 * @throws Exception
	 */
	private Map<String,Map<String,CrawlerSocialSummaryItem>> createByDateAndTypeMap(Map<String, List<CrawlerSocialSummaryItem>> typeListMap) throws Exception {
		Map<String,Map<String,CrawlerSocialSummaryItem>> sm=new TreeMap<String,Map<String,CrawlerSocialSummaryItem>>();
		a:for (Map.Entry<String, List<CrawlerSocialSummaryItem>> list : typeListMap.entrySet()) {
			for (CrawlerSocialSummaryItem social : list.getValue()) {
				Map<String,CrawlerSocialSummaryItem> m = sm.get(social.getPayTime());
				if(m==null){
					if(DateUtils.getSubMonth("yyyy-MM",-1).equals(social.getPayTime())){
						continue a;
					}
					m=new HashMap<String,CrawlerSocialSummaryItem>();
					sm.put(social.getPayTime(),m);
				}
				m.put(list.getKey(), social);
			}
		}
		return sm;
	}
	

	/**
	 * 解析社保数据
	 * @param year 
	 */
	public void analysisSocialData(Document doc, List<CrawlerSocialSummaryItem> itemList, String type, int year) {
		Elements trs = doc.select("body > table:nth-child(1) > tbody > tr");
		if (trs != null && trs.size() > 2) {
			for (int i = 2; i < trs.size(); i++) {
				String tp = trs.get(i).select("td").get(1).text();
				if (itemList.size()==0&&StringUtils.isEquals(tp, "-")) {
					continue;
				}
				Elements tds = trs.get(i).select("td");
				String rowspan = tds.get(0).attr("rowspan");
				if (StringUtils.isEquals(type, "medicalcare") &&!StringUtils.isEquals(rowspan, "1") && !StringUtils.isEquals(rowspan, "2")) {// 补基金
					continue;
				}
				CrawlerSocialSummaryItem item = new CrawlerSocialSummaryItem();
				item.setId(UUIDUtils.getUUIDStr());
				item.setCreateTime(new Date());
				item.setPayItemType(type);
				if (StringUtils.isEquals("oldage", type)) {// 养老
					item.setPayItem("养老保险");
					item.setCompanyName(trs.get(i).select("td").get(5).text());
					item.setPayTime(trs.get(i).select("td").get(0).text());
					// 正常缴纳部分
					String base = trs.get(i).select("td").get(2).text();
					if (StringUtils.isEmpty(base) || StringUtils.isEquals(base.trim(), "-")) {
						item.setPayBase(new BigDecimal(0));
					} else {
						item.setPayBase(new BigDecimal(base));
					}
					String comAmount = trs.get(i).select("td").get(3).text();
					if (StringUtils.isEmpty(comAmount) || StringUtils.isEquals(comAmount.trim(), "-")) {
						item.setComAmount(new BigDecimal(0));
					} else {
						item.setComAmount(new BigDecimal(comAmount));
					}
					String perAmount = trs.get(i).select("td").get(4).text();
					if (StringUtils.isEmpty(perAmount) || StringUtils.isEquals(perAmount.trim(), "-")) {
						item.setPerAmount(new BigDecimal(0));
					} else {
						item.setPerAmount(new BigDecimal(perAmount));
					}
				} else if (StringUtils.isEquals("unemployment", type)) {// 失业
					item.setPayItem("失业保险");
					item.setPayTime(trs.get(i).select("td").get(0).text());
					String base = trs.get(i).select("td").get(1).text();
					if (StringUtils.isEmpty(base) || StringUtils.isEquals(base.trim(), "-")) {
						item.setPayBase(new BigDecimal(0));
					} else {
						item.setPayBase(new BigDecimal(base));
					}
					String comAmount = trs.get(i).select("td").get(2).text();
					if (StringUtils.isEmpty(comAmount) || StringUtils.isEquals(comAmount.trim(), "-")) {
						item.setComAmount(new BigDecimal(0));
					} else {
						item.setComAmount(new BigDecimal(comAmount));
					}
					String perAmount = trs.get(i).select("td").get(3).text();
					if (StringUtils.isEmpty(perAmount) || StringUtils.isEquals(perAmount.trim(), "-")) {
						item.setPerAmount(new BigDecimal(0));
					} else {
						item.setPerAmount(new BigDecimal(perAmount));
					}
				} else if (StringUtils.isEquals("injuries", type)) {// 工伤
					item.setPayItem("工伤保险");
					item.setPayTime(trs.get(i).select("td").get(0).text());
					String base = trs.get(i).select("td").get(1).text();
					if (StringUtils.isEmpty(base) || StringUtils.isEquals(base.trim(), "-")) {
						item.setPayBase(new BigDecimal(0));
					} else {
						item.setPayBase(new BigDecimal(base));
					}
					String comAmount = trs.get(i).select("td").get(2).text();
					if (StringUtils.isEmpty(comAmount) || StringUtils.isEquals(comAmount.trim(), "-")) {
						item.setComAmount(new BigDecimal(0));
					} else {
						item.setComAmount(new BigDecimal(comAmount));
					}
					item.setPerAmount(new BigDecimal(0));
				} else if (StringUtils.isEquals("maternity", type)) {// 生育
					item.setPayItem("生育保险");
					item.setPayTime(trs.get(i).select("td").get(0).text());
					String base = trs.get(i).select("td").get(1).text();
					if (StringUtils.isEmpty(base) || StringUtils.isEquals(base.trim(), "-")) {
						item.setPayBase(new BigDecimal(0));
					} else {
						item.setPayBase(new BigDecimal(base));
					}
					String comAmount = trs.get(i).select("td").get(2).text();
					if (StringUtils.isEmpty(comAmount) || StringUtils.isEquals(comAmount.trim(), "-")) {
						item.setComAmount(new BigDecimal(0));
					} else {
						item.setComAmount(new BigDecimal(comAmount));
					}
					item.setPerAmount(new BigDecimal(0));
				} else if (StringUtils.isEquals("medicalcare", type)) {// 医疗
					if (StringUtils.isEquals(rowspan, "1") || StringUtils.isEquals(rowspan, "2")) {// 补基金
						item.setPayItem("医疗保险");
						item.setCompanyName(trs.get(i).select("td").get(5).text());
						item.setPayTime(trs.get(i).select("td").get(0).text());
						String base = trs.get(i).select("td").get(2).text();
						if (StringUtils.isEmpty(base) || StringUtils.isEquals(base.trim(), "-")) {
							item.setPayBase(new BigDecimal(0));
						} else {
							item.setPayBase(new BigDecimal(base));
						}
						String comAmount = trs.get(i).select("td").get(3).text();
						if (StringUtils.isEmpty(comAmount) || StringUtils.isEquals(comAmount.trim(), "-")) {
							item.setComAmount(new BigDecimal(0));
						} else {
							item.setComAmount(new BigDecimal(comAmount));
						}
						String perAmount = trs.get(i).select("td").get(4).text();
						if (StringUtils.isEmpty(perAmount) || StringUtils.isEquals(perAmount.trim(), "-")) {
							item.setPerAmount(new BigDecimal(0));
						} else {
							item.setPerAmount(new BigDecimal(perAmount));
						}
					}
					
					// 补基金部分 两行数据之和
					if (StringUtils.isEquals(rowspan, "2")) {
						String base1 = trs.get(i + 1).select("td").get(1).text();
						if (StringUtils.isNotEmpty(base1) && !StringUtils.isEquals(base1.trim(), "-")) {
							item.setPayBase(item.getPayBase().add(new BigDecimal(base1)));
						}
						String comAmount1 = trs.get(i + 1).select("td").get(2).text();
						if (StringUtils.isNotEmpty(comAmount1) && !StringUtils.isEquals(comAmount1.trim(), "-")) {
							item.setComAmount(item.getComAmount().add(new BigDecimal(comAmount1)));
						}
						String perAmount1 = trs.get(i + 1).select("td").get(3).text();
						if (StringUtils.isNotEmpty(perAmount1) && !StringUtils.isEquals(perAmount1.trim(), "-")) {
							item.setPerAmount(item.getPerAmount().add(new BigDecimal(perAmount1)));
						}
					}
				} else {
					continue;
				}

				itemList.add(item);
			}
		}else{
			//创建整年未缴数据
			if (itemList.size()>0) {
				for (int j = 1; j <= 12; j++) {
					CrawlerSocialSummaryItem item=new CrawlerSocialSummaryItem();
					item.setId(UUIDUtils.getUUIDStr());
					item.setPayTime(year+"-"+(j<10?"0"+j:j));
					item.setPayItemType(type);
					item.setPayItem(socialMap.get(type));
					item.setPayBase(new BigDecimal(0));
					item.setComAmount(new BigDecimal(0));
					item.setPerAmount(new BigDecimal(0));
					item.setCreateTime(new Date());
					item.setCompanyName("-");
					itemList.add(item);
				}
				
			}
		}

	}

	private Document crawlSocialByType(String type, Map<String, String> cookies, int year) throws Exception {
		String url = String.format(DOMAIN_URL + social, type, year, new Date().getTime());
		return Jsoup.connect(url).cookies(cookies).followRedirects(true).post();
	}

	/**
	 * 封装返回数据
	 * 
	 * @param resultMap
	 * @param isPush 
	 * @return
	 * @throws Exception
	 */
	private CrawlerSocialFundMessage setData(Map<String, String> resultMap, String status, boolean isPush) throws Exception {
		CrawlerSocialFundMessage response = new CrawlerSocialFundMessage();
		if (StringUtils.isEquals(status, RESULT_CODE.SUCCESS.key)) {
			response.setId(resultMap.get("managerId"));
			if(isPush){
				//推送消息
				try {
					log.info("Sending CrawlerSocialMessage...");
					OmMemberMessage message=new OmMemberMessage();
					message.setMemberId(resultMap.get("memberId"));
					message.setSummary("您的社保信息已更新完毕，请查阅。");//
					message.setMessageType("crawlSocial");//
					MessageProperties prop = new MessageProperties();
					prop.setContentType(MessageProperties.CONTENT_TYPE_BYTES);
					Message msg = new Message(JSON.toJSONString(message).getBytes(), prop);
					rabbitTemplate.send("message_push_queue", msg);
					log.info("Sending CrawlerSocialMessage Done");
				} catch (Exception e) {
					log.error("Sending CrawlerSocialMessage Error");
				}
			}
		}  else if (StringUtils.isEquals(status, RESULT_CODE.FAILURE.key)) {// 登录失败
			throw new BusinessException(RESULT_CODE.FAILURE.key, RESULT_CODE.FAILURE.value);
		}else if (StringUtils.isEquals(status, RESULT_CODE.PASSWORD_ERROR.key)) {
			throw new BusinessException(RESULT_CODE.PASSWORD_ERROR.key, RESULT_CODE.PASSWORD_ERROR.value);
		} else if (StringUtils.isEquals(status, RESULT_CODE.VERIFICATION_CODE_ERROR.key)) {
			throw new BusinessException(RESULT_CODE.VERIFICATION_CODE_ERROR.key,
					RESULT_CODE.VERIFICATION_CODE_ERROR.value);
		} else if (StringUtils.isEquals(status, RESULT_CODE.SYSTERM_MAINTAIN.key)) {
			throw new BusinessException(RESULT_CODE.SYSTERM_MAINTAIN.key,
					RESULT_CODE.SYSTERM_MAINTAIN.value);
		} else if (StringUtils.isEquals(status, RESULT_CODE.SOCIAL_LOCK.key)) {
			throw new BusinessException(RESULT_CODE.SOCIAL_LOCK.key,
					RESULT_CODE.SOCIAL_LOCK.value);
		}
		return response;
	}

	/**
	 * 保存社保账户信息
	 * @param resultMap
	 * @param status
	 * @param message
	 * @return
	 * @throws Exception
	 */
	private String saveSocialManagerData(Map<String, String> resultMap, String status, CrawlerSocialFundMessage message) throws Exception {
		CrawlerSfManager manager = managerService.selectById(message.getId());
		try {
			if (manager != null) {
				if (StringUtils.isEquals(status, RESULT_CODE.SUCCESS.key)) {// 登录成功
					manager.setPwd(message.getPwd());
					if (!message.getIsBatch()) {
						manager.setLoginStatus("1");// 登陆中
					}
					manager.setStatus("1");// 有效
					manager.setMemberId(resultMap.get("memberId"));
				} else if (StringUtils.isEquals(status, RESULT_CODE.PASSWORD_ERROR.key)) {// 密码错误
					manager.setLoginStatus("0");// 登陆中
					manager.setStatus("0");// 无效
				}
				managerService.updateById(manager);
			} else {// 第一次登录
				
				if (StringUtils.isEquals(status, RESULT_CODE.SUCCESS.key)) {// 登录成功
					// 创建新账号
					manager = new CrawlerSfManager();
					manager.setId(UUIDUtils.getUUIDStr());
					manager.setCityId("110000");
					manager.setCreateTime(new Date());
					manager.setIdentityId(resultMap.get("identityId"));
					manager.setPwd(resultMap.get("pwd"));
					manager.setLoginStatus("1");
					manager.setMemberId(resultMap.get("memberId"));
					manager.setName(resultMap.get("name"));
					manager.setStatus("1");// 有效
					manager.setTp("1");// 社保账户
					managerService.insert(manager);
				}
			}
		} catch (Exception e) {
			log.error("保存社保账户信息异常");
		}
		return manager==null?"":manager.getId();
	}

	/**
	 * 保存社保信息数据
	 * 
	 * @param managerId
	 * @param resultMap
	 */
	private void saveSocialInfoData(Map<String, String> resultMap) {
		
		Wrapper<CrawlerSocialInfo> socialInfo = new EntityWrapper<CrawlerSocialInfo>();
		socialInfo.eq("manager_id", resultMap.get("managerId"));
		// 社保信息
		CrawlerSocialInfo info = socialInfoService.selectOne(socialInfo);
		if (info==null) {
			info = new CrawlerSocialInfo();
			info.setId(UUIDUtils.getUUIDStr());
			info.setCreateTime(new Date());
			info.setManagerId(resultMap.get("managerId"));
		}
		info.setUpdateTime(new Date());
		info.setSocialCompany(resultMap.get("company"));
		info.setPayStatus(resultMap.get("status"));
		String base = resultMap.get("base");
		if (StringUtils.isNotEmpty(base)) {
			info.setSocialBase(new BigDecimal(base));
		}
		socialInfoService.insertOrUpdate(info);

	}

}
